package luj.tool.jnproxyan.proxy.network.socksv2.server.handler;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.HttpObject;
import io.netty.handler.codec.http.HttpRequest;
import luj.cluster.api.actor.Tellable;
import luj.tool.jnproxyan.framework.lujnet.ConnState;
import luj.tool.jnproxyan.proxy.network.logger.Client2pLogger;
import luj.tool.jnproxyan.proxy.network.socks.actor.root.message.http.client2p.request.add.C2pHttpRequestMsg;
import luj.tool.jnproxyan.proxy.network.socksv2.connection.ConnStateAttr;
import luj.tool.jnproxyan.framework.proxy.actor.tell.ActorTeller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.Instant;

/**
 * 将浏览器发过来的网页请求，先统一加到请求队列
 *
 * @see luj.tool.jnproxyan.proxy.network.socks.actor.root.message.http.client2p.request.add.OnC2pHttpReq#onHandle
 */
@Component
final class ReceiveHttpReqHandler extends SimpleChannelInboundHandler<HttpObject> {

  public ReceiveHttpReqHandler inject(Tellable socksRef) {
    var result = new ReceiveHttpReqHandler();
    result._socksRef = socksRef;
    result._actorTeller = _actorTeller;
    return result;
  }

  @Override
  protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) {
    ConnState c2pConn = new ConnStateAttr(ctx.channel()).get();
    Long socksId = c2pConn.getReqId();

    new Client2pLogger(LOG, socksId).log("接收<浏>W请求：{}", msg.getClass().getName());
    if (msg instanceof HttpRequest) {
      LOG.debug("URI#{}：{}", socksId, ((HttpRequest) msg).uri());
    }

    _actorTeller.inject(_socksRef).tell(C2pHttpRequestMsg.class, (b, m) -> b
        .f(m::socksId).set(socksId)
        .f(m::data).set(msg)
        .f(m::requestTime).set(Instant.now())
    );
  }

  private static final Logger LOG = LoggerFactory.getLogger(ReceiveHttpReqHandler.class);

  Tellable _socksRef;

  @Autowired
  ActorTeller _actorTeller;
}
